package com.demomaster.quickaccessibility.service;

import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED;

import android.Manifest;
import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityWindowInfo;

import java.util.HashMap;
import java.util.Map;


public class BaseAccessibilityService extends AccessibilityService {
    public static final String TAG = BaseAccessibilityService.class.getSimpleName();
    public static BaseAccessibilityService instance;
    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
        handler = new Handler();
        QuickAccessibility.getInstance().onServiceCreate(instance);
    }

    //初始化
    @Override
    protected void onServiceConnected() {
        super.onServiceConnected();
        Log.d(TAG, "无障碍服务【开启】");

        AccessibilityServiceInfo serviceInfo = getServiceInfo();
        if (serviceInfo == null) {
            serviceInfo = new AccessibilityServiceInfo();
        }
        serviceInfo.notificationTimeout = 3000;
        setServiceInfo(serviceInfo);

        // AccessibilityHelper.onServiceConnected(this);
    }

    private String currentActivityName;
    String lastActivityName;
    private String currentPackageName;

    public String getCurrentActivityName() {
        return currentActivityName;
    }

    public String getCurrentPackageName() {
        AccessibilityNodeInfo accessibilityNodeInfo = getRootInActiveWindow();
        if(accessibilityNodeInfo!=null) {
            return accessibilityNodeInfo.getPackageName() + "";
        }
        return null;
    }
    AccessibilityNodeInfo rootNodeInfo;
    long lastGetRootNodeTime;
    @Override
    public AccessibilityNodeInfo getRootInActiveWindow() {
//        long t1 = System.currentTimeMillis();
//        if(t1-lastGetRootNodeTime>100) {//控制100ms内只获取一次
//            lastGetRootNodeTime = t1;
//            rootNodeInfo = super.getRootInActiveWindow();
//        }
        //Log.d(TAG, "getRootInActiveWindow 耗时：" + (System.currentTimeMillis() - t1)+",root="+(rootNodeInfo!=null));
        return super.getRootInActiveWindow();
        //int count = filterWindow(accessibilityNodeInfo);
        //QDLogger.println("getRootInActiveWindow count:"+count);
        //return accessibilityNodeInfo;
    }

    private int filterWindow(AccessibilityNodeInfo accessibilityNodeInfo) {
        int c = 0;
        if (accessibilityNodeInfo != null) {
            c = c + 1;
            if (accessibilityNodeInfo.getChildCount() > 0) {
                for (int i = 0; i < accessibilityNodeInfo.getChildCount(); i++) {
                    c = c + filterWindow(accessibilityNodeInfo.getChild(i));
                }
            }
        }

        return c;
    }

    public AccessibilityWindowInfo getWindowById(int id) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            for (AccessibilityWindowInfo windowInfo : getWindows()) {
                if (windowInfo.getId() == id) {
                    return windowInfo;
                }
            }
        }
        return null;
    }

    public AccessibilityWindowInfo getTopWindow() {
        AccessibilityWindowInfo topWindowInfo = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            for (AccessibilityWindowInfo windowInfo : getWindows()) {
                if (topWindowInfo == null) {
                    topWindowInfo = windowInfo;
                } else {
                    if (topWindowInfo.getLayer() < windowInfo.getLayer()) {
                        topWindowInfo = windowInfo;
                    }
                }
                //QDLogger.println("windowInfo=" + windowInfo.toString());
            }
        }
        return topWindowInfo;
    }

    long lastTime = 0;
    QuickAccessibilityEvent delayEvent;
    Handler handler;
    Runnable delayRunnable = new Runnable() {
        @Override
        public void run() {
            if (delayEvent != null) {
                //QuickEvent.getDefault().post(new EventMessage(QuickAccessibilityService_Event, delayEvent));
                QuickAccessibility.getInstance().onAccessibilityEvent(delayEvent);
            }
        }
    };

    //实现辅助功能
    @Override
    public void onAccessibilityEvent(android.view.accessibility.AccessibilityEvent event) {
        int eventType = event.getEventType();
        //Log.i("onAccessibilityEvent:",""+ eventType);
        switch (eventType) {
            case android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
                Log.d(TAG,"窗口信息，当前包名:" + currentPackageName + ",页面:" + currentActivityName);
                AccessibilityNodeInfo accessibilityNodeInfo = getRootInActiveWindow();
                if (accessibilityNodeInfo != null) {
                    Log.d(TAG,"TYPE_WINDOW_STATE_CHANGED_0:" + event.getWindowId() + "]" + event.getPackageName() + "<===>" + event.getClassName() + ",root=" + accessibilityNodeInfo.getWindowId() + "]" + accessibilityNodeInfo.getPackageName() + ",act=" + accessibilityNodeInfo.getClassName());
                    if (!TextUtils.isEmpty(event.getPackageName())&&event.getPackageName().equals(accessibilityNodeInfo.getPackageName())) {
                        setLatestComponent(accessibilityNodeInfo.getPackageName(), event.getClassName());
                    }
                } else {
                    setLatestComponent(event.getPackageName(), event.getClassName());
                    Log.d(TAG,"TYPE_WINDOW_STATE_CHANGED_3:" + event.getWindowId() + "]" + event.getPackageName() + "<===>" + event.getClassName());
                }
                break;
            default:
                break;
        }

        //处理延迟事件 处理频繁事件的相应周期
        if (eventType == TYPE_WINDOW_CONTENT_CHANGED) {
            long t1 = System.currentTimeMillis() - lastTime;
            if (t1 < 200) {
                delayEvent = new QuickAccessibilityEvent(event);
                handler.removeCallbacks(delayRunnable);
                handler.postDelayed(delayRunnable, 200);
                return;
            }else {
                lastTime = System.currentTimeMillis();
            }
        }

        //AccessNodeFinder.getInstance().noteUpdate();
        QuickAccessibility.getInstance().onAccessibilityEvent(new QuickAccessibilityEvent(event));
        //AccessibilityHelper.onAccessibilityEvent(this, event);
        /*
        switch (eventType) {
            case AccessibilityEvent.TYPE_VIEW_CLICKED:
                Log.i(TAG, "捕获到点击事件");
                AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
                if (nodeInfo != null) {
                    // 查找text为Test!的控件
                    List<AccessibilityNodeInfo> button = nodeInfo.findAccessibilityNodeInfosByText("Test!");
                    nodeInfo.recycle();
                    for (AccessibilityNodeInfo item : button) {
                        Log.i(TAG, "long-click button!");
                        // 执行长按操作
                        item.performAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);
                        item.getParent().performAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);
                    }
                }
                break;
            case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
                //Log.e(TAG, "窗口切换" + event.getClassName());
                break;
            case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED:
                //Log.e(TAG, "文字改变" + event.getClassName());
                break;
        }*/
        //  }
    }

    public void setLatestComponent(CharSequence packageName, CharSequence className) {
        String packageNameStr = packageName == null ? null : packageName.toString();
        String classNameStr = className == null ? null : className.toString();
        if (!TextUtils.isEmpty(packageNameStr)) {
            boolean changePackage = false;//包名改变
            if (!packageNameStr.equals(currentPackageName)) {
                changePackage = true;
            }
            currentPackageName = packageNameStr;
            if (!TextUtils.isEmpty(classNameStr) && isActivityExists(packageNameStr, classNameStr)) {
                currentActivityName = classNameStr;
                lastActivityName = classNameStr;
                Log.d(TAG,"窗口更新，当前包名:" + currentPackageName + ",当前页面:" + currentActivityName+",上一页面："+lastActivityName);
                return;
            }
            if (changePackage && !TextUtils.isEmpty(currentActivityName)) {
                Log.d(TAG,"页面滞空:" + currentActivityName);
                currentActivityName = null;
            }
        }
        //currentActivityName = null;
    }

    private boolean isActivityExists(String packageName, String activityName) {
        if (isPackageExists(packageName)) {
            try {
                ComponentName componentName = new ComponentName(
                        packageName,
                        activityName
                );
                ActivityInfo activityInfo = getPackageManager().getActivityInfo(componentName, 0);
                if (activityInfo != null) {
                    return true;
                }
            } catch (PackageManager.NameNotFoundException e) {

            }
        }
        return false;
    }

    private boolean isPackageExists(String packageName) {
        try {
            PackageInfo packageInfo = getPackageManager().getPackageInfo(packageName, 0);
            if (packageInfo != null) {
                return true;
            }
        } catch (PackageManager.NameNotFoundException e) {

        }
        return false;
    }

    private void ansyActivity(String packageName, String className) {
        try {
            ComponentName componentName = new ComponentName(
                    packageName,
                    className
            );
            ActivityInfo activityInfo = getPackageManager().getActivityInfo(componentName, 0);
            if (activityInfo != null && !TextUtils.isEmpty(activityInfo.toString())) {// 匹配成功
                currentPackageName = packageName;
                String activityName = activityInfo.toString();
                currentActivityName = activityName.substring(activityName.indexOf(" "), activityName.indexOf("}")).trim();
                Log.d(TAG,"窗口update，包名:" + currentPackageName + ",页面:" + currentActivityName);
            }
        } catch (PackageManager.NameNotFoundException e) {
            //e.printStackTrace();
//            String topActivityName = QuickActivityManager.getTopActivity(QuickAccessibilityService.instance.getApplicationContext());
//            if (!TextUtils.isEmpty(topActivityName)&&!topActivityName.equals(currentActivityName)) {// 匹配成功
//                currentActivityName = topActivityName;
//            }
        }
    }

    /**
     * 模拟全局按键 performGlobalAction "Android 4.1及以上系统才支持此功能
     */
    @Override
    public void onInterrupt() {
        Log.d(TAG,"辅助功能被迫中断");
    }

    @Override
    public void onDestroy() {
        QuickAccessibility.getInstance().onServiceDestroy();
        instance = null;
        super.onDestroy();
        Log.i(TAG, "辅助功能已关闭");
    }

    //跳转系统自带界面 辅助功能界面
    public static void startSettintActivity(Context context) {
        /*Intent intent = new Intent(context, DialogWindowActivity.class);
        Bundle bundle = new Bundle();
        bundle.putString("permission", Manifest.permission.BIND_ACCESSIBILITY_SERVICE);
        intent.putExtras(bundle);
        (context).startActivity(intent);*/
        //TODO QuickPermission.with().permissions(new String[]{Manifest.permission.BIND_ACCESSIBILITY_SERVICE}).request();
    }

    /**
     * 添加要监听的包名
     *
     * @param packageName
     */
    public static void addPackage(String packageName) {
        packageMap.put(packageName, "");
        resetPackage();
    }

    /**
     * 重置服务包名（需要服务启动时执行）
     */
    public static void resetPackage() {
        if (instance != null) {
            AccessibilityServiceInfo serviceInfo = instance.getServiceInfo();
            if (serviceInfo != null) {
                if (serviceInfo.packageNames != null) {
                    for (String packageName : serviceInfo.packageNames) {
                        packageMap.put(packageName, packageName);
                    }
                }
                String[] arr = new String[packageMap.size()];
                int i = 0;
                for (Map.Entry entry : packageMap.entrySet()) {
                    arr[i] = (String) entry.getKey();
                    i++;
                }
                serviceInfo.packageNames = arr;
                serviceInfo.notificationTimeout = 3000;
                instance.setServiceInfo(serviceInfo);
            }
        }
    }

    public static final Map<String, String> packageMap = new HashMap<>();

    public void performGlobalAction(AccessibilityAction eventMessage) {
        if (eventMessage != null) {
            performGlobalAction(eventMessage.action);
        }
    }

}
